package com.cq.hd.order.factory;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cq.hd.common.enums.biz.*;
import com.cq.hd.common.response.Throw;
import com.cq.hd.common.utils.NoUtils;
import com.cq.hd.member.api.TbBusinessMerchantApi;
import com.cq.hd.member.api.vo.BusinessMerchantVo;
import com.cq.hd.member.api.vo.BusinessPointsMallProductVo;
import com.cq.hd.order.api.dto.CreateOrderDto;
import com.cq.hd.order.api.vo.CreateOrderVo;
import com.cq.hd.order.mapper.TbOrderItemMapper;
import com.cq.hd.order.mapper.TbOrderMapper;
import com.cq.hd.order.po.TbOrderItemPo;
import com.cq.hd.order.po.TbOrderPo;
import com.cq.hd.product.api.vo.ActiveVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.stream.Collectors;

@Component
@Slf4j
public class PointsOrderHandler extends AbstractOrderHandler {

    @Autowired
    private TbOrderMapper orderMapper;

    @Autowired
    private TbOrderItemMapper orderItemMapper;

    @Autowired
    private TbBusinessMerchantApi businessMerchantApi;

    @Autowired
    private PlatformTransactionManager transactionManager;

    @Override
    protected Integer getType() {
        return ActiveTypeEnum.POINTS.getValue();
    }

    @Override
    public CreateOrderVo createOrder(CreateOrderDto createOrderDto, ActiveVo activeVo) {
        return null;
    }

    @Override
    public CreateOrderVo createPointsOrder(CreateOrderDto createOrderDto, BusinessPointsMallProductVo productVo) {
        Long userId = createOrderDto.getUserId();
        Long businessId = productVo.getBusinessId();

        LocalDateTime now = LocalDateTime.now();

        // 生成订单号
        String orderNo = NoUtils.getActiveOrderNo();
        Long orderId = 0L;

        // 查询商家数据，获取商家自有商户id
        BusinessMerchantVo businessMerchantVo = businessMerchantApi.getOwnByBusinessId(businessId, OwnStateEnum.YES.getValue()).unpack();
        Long merchantId = businessMerchantVo.getMerchantId();

        TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionAttribute());

        try {
            LocalDateTime endTime = now.plusDays(productVo.getDayLimit()).with(LocalTime.MAX);

            // 创建订单数据
            TbOrderPo tbOrderPo = new TbOrderPo();
            tbOrderPo.setBusinessId(businessId);
            tbOrderPo.setActiveId(0L);
            tbOrderPo.setAgentId(0L);
            tbOrderPo.setAgent2Id(0L);
            tbOrderPo.setUserId(userId);
            tbOrderPo.setActiveShareCode("");
            tbOrderPo.setOrderNo(orderNo);
            tbOrderPo.setOrderType(getType());
            tbOrderPo.setMerchantId(merchantId); // 商家自有商户id
            tbOrderPo.setActiveTitle(productVo.getGoodsName());
            tbOrderPo.setActiveImg(productVo.getGoodsImages().get(0));
            tbOrderPo.setStartTime(now);
            tbOrderPo.setEndTime(endTime);
            tbOrderPo.setValidStartTime(now);
            tbOrderPo.setValidEndTime(endTime);
            tbOrderPo.setSubsidyState(0);
            tbOrderPo.setDiscountState(1);
            tbOrderPo.setStepPriceState(1);
            tbOrderPo.setAgentState(1);
            tbOrderPo.setVerifyMethod(1);
            tbOrderPo.setTotalStock(productVo.getTotalNum());
            tbOrderPo.setOrderState(OrderStateEnum.WAIT_VERIFY.getValue());
            tbOrderPo.setPayTime(now);
            tbOrderPo.setZeroState(1);
            tbOrderPo.setOrderNum(1);
            tbOrderPo.setActivePrice(productVo.getAmount());
            tbOrderPo.setOrderPrice(productVo.getAmount());
            tbOrderPo.setPayPrice(productVo.getRequiredPoints());
            tbOrderPo.setRedPacketBillId(0L);
            tbOrderPo.setRedPacketAmt(BigDecimal.ZERO);
            tbOrderPo.setDiscountAmt(BigDecimal.ZERO);
            tbOrderPo.setOrderIncomeAmt(BigDecimal.ZERO);
            tbOrderPo.setCommissionAmt(BigDecimal.ZERO);
            tbOrderPo.setCommissionRate(BigDecimal.ZERO);
            tbOrderPo.setOtherEquity("");
            tbOrderPo.setExclusiveCommissionRate(BigDecimal.ZERO);
            tbOrderPo.setCalCommissionType(0);
            tbOrderPo.setActualCommissionAmt(BigDecimal.ZERO);
            tbOrderPo.setSubAgentCommissionRate(BigDecimal.ZERO);
            tbOrderPo.setSubAgentCommissionAmt(BigDecimal.ZERO);
            tbOrderPo.setUserPointsAmt(BigDecimal.ZERO);
            tbOrderPo.setAgentPointsAmt(BigDecimal.ZERO);
            tbOrderPo.setSubAgentPointsAmt(BigDecimal.ZERO);
            tbOrderPo.setOrderTime(now);
            tbOrderPo.setCreateTime(now);
            tbOrderPo.setUpdateTime(now);
            int insert = orderMapper.insert(tbOrderPo);
            if (insert == 0) {
                Throw.isBusinessException("积分订单生成失败");
            }
            orderId = tbOrderPo.getId();

            // 生成核销码
            String verifyCode;
            while (true) {
                verifyCode = NoUtils.getVerifyCode();
                Integer verifyCodeCount = orderItemMapper.selectCount(new QueryWrapper<TbOrderItemPo>().eq("verify_code", verifyCode));
                if (verifyCodeCount == null || verifyCodeCount <= 0) {
                    break;
                }
            }

            // 生成子订单号
            String subOrderNo = NoUtils.getActiveSubOrderNo();

            String goodsId = productVo.getMerchantIds()
                    .stream()
                    .map(String::valueOf)
                    .collect(Collectors.joining(","));

            TbOrderItemPo tbOrderItemPo = new TbOrderItemPo();
            tbOrderItemPo.setItemGroup(1);
            tbOrderItemPo.setBusinessId(businessId);
            tbOrderItemPo.setActiveId(0L);
            tbOrderItemPo.setAgentId(0L);
            tbOrderItemPo.setAgent2Id(0L);
            tbOrderItemPo.setOrderId(orderId);
            tbOrderItemPo.setUserId(userId);
            tbOrderItemPo.setActiveGoodsId(0L);
            tbOrderItemPo.setSubOrderNo(subOrderNo);
            tbOrderItemPo.setOrderType(getType());
            tbOrderItemPo.setMerchantId(0L);
            tbOrderItemPo.setGoodsId(goodsId);
            tbOrderItemPo.setMulState(2);
            tbOrderItemPo.setGoodsName(productVo.getGoodsName());
            tbOrderItemPo.setGoodsImgs(productVo.getGoodsImages().get(0));
            tbOrderItemPo.setGoodsPrice(productVo.getAmount());
            tbOrderItemPo.setGoodsNum(1);
            tbOrderItemPo.setVerifyCode(verifyCode);
            tbOrderItemPo.setMerchantAmt(BigDecimal.ZERO);
            tbOrderItemPo.setMerchantSubsidyAmt(productVo.getAmount());
            tbOrderItemPo.setCommissionAmt(BigDecimal.ZERO);
            tbOrderItemPo.setSubAgentCommissionAmt(BigDecimal.ZERO);
            tbOrderItemPo.setRedPacketAmt(BigDecimal.ZERO);
            tbOrderItemPo.setTotalSubsidyAmt(productVo.getAmount());
            tbOrderItemPo.setDistributionOrderAmt(BigDecimal.ZERO);
            tbOrderItemPo.setReturnAmt(BigDecimal.ZERO);
            tbOrderItemPo.setSubOrderState(SubOrderStateEnum.WAIT_VERIFY.getValue());
            tbOrderItemPo.setSettleState(SettleStateEnum.NO.getValue());
            tbOrderItemPo.setOrderTime(tbOrderPo.getOrderTime());
            tbOrderItemPo.setExpireTime(endTime);
            tbOrderItemPo.setCreateTime(now);
            tbOrderItemPo.setUpdateTime(now);

            insert = orderItemMapper.insert(tbOrderItemPo);
            if (insert == 0) {
                Throw.isBusinessException("下单失败");
            }

            transactionManager.commit(transaction);
        } catch (Exception e) {
            //回滚事务
            transactionManager.rollback(transaction);
            log.error("<创建积分订单>事务异常回滚", e);
            Throw.isBusinessException(e.getMessage());
        }

        CreateOrderVo createOrderVo = new CreateOrderVo();
        createOrderVo.setOrderId(orderId);
        createOrderVo.setOrderNo(orderNo);
        createOrderVo.setZeroState(1);

        return createOrderVo;
    }
}
